(SST) ShlWAPI.pas Version 1.08

Developer Reference
(SST)ShlWAPI ParseURL Function
Determines and extracts the relevant compoments from a Uniform Resource Locator (URL).
Scope
Global (i.e. this function can be called/accessed from code in any unit that includes/uses (SST)ShlWAPI.pas).
Syntax
function ParseURL(pcszURL : LPCSTR; VAR ppu : PARSEDURL) : HRESULT;
Parameters
pcszURL [in] Depending on which version of the function is called, a pointer to either a null-terminated ANSI (ParseURL & ParseURLA) or Unicode (ParseURLW) string.
ppu [in/out] Variable of type PARSEDURL (= PARSEDURLA) if the ANSI or PARSEDURLW if the wide character (i.e. Unicode) version of the function is called.
Return Values
If the function succeeded in parsing the URL (specified in the first parameter, pcszURL), it returns S_OK (= 0). If the function fails it returns a Component Object Model (COM) error code. Error codes typically returned for common errors, such as failing to initialize the cbSize member of the recprd or an invalid URL string, are 0x80070057 (-2147024809 = ERROR_INVALID_PARAMETER) and 0x80041001 (-2147217407 = URL_E_INVALID_SYNTAX).
Remarks
The string pointers returned by the function via the record are merely pointers to parts within the URL, input string (pcszURL). The terminating null-character of these string pointers (pszProtocol & pszSuffix) is therefore always that of the string passed to the function by the caller. For this reason, it is advisable that the caller, prior to evaluating the parts that are the URL's protocol and suffix, copies the number of characters returned in the cchProtocol and cchSuffix members into separate strings (e.g. myUrlSuffix := Copy(parsedUrlVar.pszSuffix, 1, parsedUrlVar.cchSuffix)).
The function is exported by name as of ShlWAPI.dll version 6.0 under Windows Vista, but according to the declaration and documentation it's supported as of ShlWAPI.dll 5.0 under Windows 2000. Unfortunately, the Microsoft SDKs, up to and including version 6.1, did not contain information on the ordinals by which the functions can be imported on systems pre-dating Vista.
Although, with the tests we ran under Win 9x and NT 4.0 (with IE 5.0), we were able to confirm that the function is exported by ordinals 1 and 2 down to ShlWAPI.dll version 5.0 (and thereby the documented min. version in the doc. accompanying Ms SDK 6.1), our assumption that the function is exported by these ordinals under ShlWAPI.dll version 4.71 remains uncomfirmed, because we did not have a system with this version. Nontheless, based on the low, numerical value of the ordinals, it's highly probable that both functions are supported as of version 4.71 and that they can be imported as under other ShlWAPI.dll versions pre-dating Vista (i.e. by their ordinals: 1 (ParseURL & ParseURLA) & 2 (ParseURLW)). However, without proof, we have specified the lowest confirmed version in the Requirements Table, below.
Example
PROCEDURE TForm4.TestShlWAPIParseURL(Sender : TObject); VAR url : STRING; VAR wcharurl : WideString; VAR urlinfo : PARSEDURLA; VAR wcharurlinfo : PARSEDURLW; VAR apiretval : HRESULT; VAR newinfoline : STRING; BEGIN url := ''; wcharurl := ''; FillChar(urlinfo, SizeOf(urlinfo), #0); FillChar(wcharurlinfo, SizeOf(wcharurlinfo), #0); apiretval := S_OK; //S_OK = 0 newinfoline := ''; url := 'http://stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm'; urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := 'Protocol : ' + urlinfo.pszProtocol + ' (cchProtocol: ' + IntToStr(urlinfo.cchProtocol) + ' characters)'; Memo1.Lines.Add(newinfoline); newinfoline := 'Suffix : ' + urlinfo.pszSuffix + ' (cchSuffix: ' + IntToStr(urlinfo.cchSuffix) + ' characters)'; Memo1.Lines.Add(newinfoline); newinfoline := 'Scheme: ' + IntToStr(urlinfo.nScheme); Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := 'http://stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm'; urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := Format('Protocol : %.*s', [urlinfo.cchProtocol, urlinfo.pszProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Protocol string length (cchProtocol) : %d', [urlinfo.cchProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix : %.*s', [urlinfo.cchSuffix, urlinfo.pszSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix string length (cchSuffix) : %d', [urlinfo.cchSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := 'Scheme: ' + IntToStr(urlinfo.nScheme); Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := 'ftp://ftp.tex.ac.uk/tex-archive/systems/unix/unixtex.ftp'; urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := Format('Protocol : %.*s', [urlinfo.cchProtocol, urlinfo.pszProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Protocol string length (cchProtocol) : %d', [urlinfo.cchProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix : %.*s', [urlinfo.cchSuffix, urlinfo.pszSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix string length (cchSuffix) : %d', [urlinfo.cchSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := 'Scheme: ' + IntToStr(urlinfo.nScheme); Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := 'mailto:dummy-address@nomail.net'; urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := Format('Protocol : %.*s', [urlinfo.cchProtocol, urlinfo.pszProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Protocol string length (cchProtocol) : %d', [urlinfo.cchProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix : %.*s', [urlinfo.cchSuffix, urlinfo.pszSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix string length (cchSuffix) : %d', [urlinfo.cchSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := 'Scheme: ' + IntToStr(urlinfo.nScheme); Memo1.Lines.Add(newinfoline); //newinfoline := Copy(urlinfo.pszSuffix, 1, urlinfo.cchSuffix) END; Memo1.Lines.Add('-- -- -- -- --'); FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := 'file://C:\Users\Administrator\Documents\Example.txt'; urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := Format('Protocol : %.*s', [urlinfo.cchProtocol, urlinfo.pszProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Protocol string length (cchProtocol) : %d', [urlinfo.cchProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix : %.*s', [urlinfo.cchSuffix, urlinfo.pszSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix string length (cchSuffix) : %d', [urlinfo.cchSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := 'Scheme: ' + IntToStr(urlinfo.nScheme); Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); //Wide character/Unicode version FillChar(wcharurlinfo, SizeOf(wcharurlinfo), #0); apiretval := S_OK; newinfoline := ''; wcharurl := 'https://stoelzelsoftwaretech.com/en/sitemap/TitleIndex.htm'; wcharurlinfo.cbSize := SizeOf(wcharurlinfo); apiretval := ParseURLW(PWideChar(wcharurl), wcharurlinfo); newinfoline := 'ParseURL called with the Unicode URL ' + AnsiQuotedStr(wcharurl, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := Format('Protocol : %.*s', [wcharurlinfo.cchProtocol, wcharurlinfo.pszProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Protocol string length (cchProtocol) : %d', [wcharurlinfo.cchProtocol]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix : %.*s', [wcharurlinfo.cchSuffix, wcharurlinfo.pszSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := Format('Suffix string length (cchSuffix) : %d', [wcharurlinfo.cchSuffix]); Memo1.Lines.Add(newinfoline); newinfoline := 'Scheme: ' + IntToStr(wcharurlinfo.nScheme); Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); //Provoke some errors FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := ''; urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(NIL, urlinfo); //Invalid pointer ! newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := 'This implementation of ParseURL is capable of handling an invalid pointer to an ANSI string'; Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := ''; //Invalid URL string ! urlinfo.cbSize := SizeOf(urlinfo); apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := 'This implementation of ParseURL is capable of handling an empty URL string'; Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add('-- -- -- -- --'); FillChar(urlinfo, SizeOf(urlinfo), #0); apiretval := S_OK; newinfoline := ''; url := 'gopher:'; //urlinfo.cbSize := SizeOf(urlinfo); //Size of record/struct NOT defined ! apiretval := ParseURL(PChar(url), urlinfo); newinfoline := 'ParseURL called with ' + AnsiQuotedStr(url, '"') + ' returned : 0x' + IntToHex(apiretval, 8) + ' (' + IntToStr(apiretval) + ')'; Memo1.Lines.Add(newinfoline); IF apiretval = S_OK THEN BEGIN newinfoline := 'This implementation of ParseURL is capable of handling incorrectly initialized PARSEDURLA structs'; Memo1.Lines.Add(newinfoline); END; Memo1.Lines.Add(''); END;
The above code sample generally produces the following output:
ParseURL called with "http://stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm" returned : 0x00000000 (0) Protocol : http://stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm (cchProtocol: 4 characters) Suffix : //stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm (cchSuffix: 59 characters) Scheme: 2 -- -- -- -- -- ParseURL called with "http://stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm" returned : 0x00000000 (0) Protocol : http Protocol string length (cchProtocol) : 4 Suffix : //stoelzelsoftwaretech.com/en/devlib/functions/ParseURL.htm Suffix string length (cchSuffix) : 59 Scheme: 2 -- -- -- -- -- ParseURL called with "ftp://ftp.tex.ac.uk/tex-archive/systems/unix/unixtex.ftp" returned : 0x00000000 (0) Protocol : ftp Protocol string length (cchProtocol) : 3 Suffix : //ftp.tex.ac.uk/tex-archive/systems/unix/unixtex.ftp Suffix string length (cchSuffix) : 52 Scheme: 1 -- -- -- -- -- ParseURL called with "mailto:dummy-address@nomail.net" returned : 0x00000000 (0) Protocol : mailto Protocol string length (cchProtocol) : 6 Suffix : dummy-address@nomail.net Suffix string length (cchSuffix) : 24 Scheme: 4 -- -- -- -- -- ParseURL called with "file://C:\Users\Administrator\Documents\Example.txt" returned : 0x00000000 (0) Protocol : file Protocol string length (cchProtocol) : 4 Suffix : C:\Users\Administrator\Documents\Example.txt Suffix string length (cchSuffix) : 44 Scheme: 9 -- -- -- -- -- ParseURL called with the Unicode URL "https://stoelzelsoftwaretech.com/en/sitemap/TitleIndex.htm" returned : 0x00000000 (0) Protocol : https Protocol string length (cchProtocol) : 5 Suffix : //stoelzelsoftwaretech.com/en/sitemap/TitleIndex.htm Suffix string length (cchSuffix) : 52 Scheme: 11 -- -- -- -- -- ParseURL called with "" returned : 0x80070057 (-2147024809) -- -- -- -- -- ParseURL called with "" returned : 0x80041001 (-2147217407) -- -- -- -- -- ParseURL called with "gopher:" returned : 0x80070057 (-2147024809)
Requirements
Unit: Declared and imported in (SST)ShlWAPI.pas
Library: (SST)ShlWAPI.dcu/(SST)ShlWAPI.obj
Unicode: Implemented as ANSI (ParseURL and ParseURLA) and Unicode (ParseURLW) functions.
Min. ShlWAPI.dll version according to MS SDK doc.: 5.0
Min. ShlWAPI.dll version based on SST research: 5.0
Min. OS version(s) according to Microsoft SDK doc.: Windows 2000, Windows 2000 Server, Windows XP, Windows Server 2003
Min. OS version(s) according to SST research.: Windows 98 with IE 5.0, Windows NT 4.0 with IE 5.0, Windows 2000
See Also
PARSEDURL, URL_SCHEME, PathIsUNC.
 
Windows APIs: ParseURL, tagPARSEDURL, PARSEDURL


Document/Contents version 1.00
Page/URI last updated on 07.12.2023
 
Copyright © Stoelzel Software Technologie (SST) 2010 - 2017
Suggestions and comments mail to:
webmaster@stoelzelsoftwaretech.com